using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using FluentIoC.Configuration.Commands;
using FluentIoC.Helpers;
using FluentIoC.Interfaces;

namespace FluentIoC.Configuration
{
    public class ContainerConfiguration
    {
        private List<IRegistration> _registrations = new List<IRegistration>();
        
        public string Environment { get; protected set; }
        public IConventions Conventions { get; protected set; }

        public ContainerConfiguration()
        {
            Environment = GetType().Name;
        }

        public ContainerConfiguration(string environment)
        {
            Environment = environment;    
        }

        public RegisterService Register<T>()
        {
            return Register(typeof (T));
        }

        public RegisterService Register<T>(string key)
        {
            return Register(typeof (T), key);
        }

        public RegisterService Register(Type type)
        {
            return Register(type, type.GetDefaultKey());
        }

        public RegisterService Register(Type type, string key)
        {
            var registraion = new RegisterService(type, key);

            _registrations.Add(registraion);

            return registraion;
        }

        public RegisterAssembly RegisterAssembly(string assembly)
        {
            var registration =  new RegisterAssembly(assembly);

            _registrations.Add(registration);

            return registration;
        }

        public void UsingConventions(IConventions conventions)
        {
            Conventions = conventions;
        }
        
        public void Configure(IIoCConfiguration configuration)
        {
            if(null != Conventions)
            {
                _registrations = _registrations.Where(r => r.IsValid(Conventions)).ToList();
            }

            var services = GetServices(_registrations);            

            foreach(var registration in _registrations)
            {
                registration.Configure(configuration, services);
            }
        }

        private Dictionary<Type, string> GetServices(IEnumerable<IRegistration> registrations)
        {
            var services = new Dictionary<Type, string>();

            foreach(var r in registrations)
            {
                foreach(var s in r.Services)
                {
                    services[s.Key] = s.Value;
                }
            }

            return services;
        }
    }
}